<?php
include_once 'php-sdk/src/facebook.php';

if (!function_exists('curl_init')) {
	throw new Exception('CURL PHP extension not available.');
}

class FBConnectorException extends Exception
{
	public function __construct($message){
		parent::__construct($message, 0);
	}
}

/**
 *
 * FB Connection handling class
 * @author duminda
 *
 */
class FBConnector
{
	/**
	 *	Appliction id
	 */
	private $app_id;

	/**
	 * Application secret code
	 */
	private $app_secret;

	/**
	 * Redirect URL
	 */
	private	$redirect_url;

	/**
	 * Logged in user ID
	 */
	protected $user_id;

	/**
	 * User access token
	 */
	protected $access_token;

	/**
	 * Facebook SDK instance
	 */
	protected $facebook;
	
	/**
	 * 
	 */
	protected $friends = null;

	/**
	 *
	 */
	protected $is_connected;

	/**
	 *
	 * FB Connection implmentation
	 * @param $appId - Appliction ID
	 * @param $appSecret - Appliction secret
	 * @param $redirectURL - Redirect URL
	 */

	public function __construct($registry) {
		if (!session_id()) {
			session_start();
		}

		require_once 'registry/registry.class.php';
		
		$this->app_id = $registry->getSetting('appid');
		$this->app_secret = $registry->getSetting('appsecret');
		$this->redirect_url = $registry->getSetting('redirecturl');
		$this->is_connected = false;
	}

	/**
	 *
	 * Connect and authenticate with FB
	 * @param user permissoins $permissions
	 * @param fileupload supported $isFileUpload
	 */
	public function connect($permissions, $isFileUpload){

		$permissonStr = $permissions;

		if (empty($_REQUEST['code'])){
			$_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection
			$appLoginUrl = "http://www.facebook.com/dialog/oauth?client_id="
			. $this->app_id . "&redirect_uri=" . urlencode($this->redirect_url)."&scope=".$permissonStr
			."&state=". $_SESSION['state'];

			echo("<script> top.location.href='" . $appLoginUrl . "'</script>");
		}
		else {
			$code = $_REQUEST['code'];

			if($_REQUEST['state'] == $_SESSION['state']) {
				$token_url = "https://graph.facebook.com/oauth/access_token?"
				. "client_id=" . $this->app_id . "&redirect_uri=" . urlencode($this->redirect_url)
				. "&client_secret=" . $this->app_secret . "&code=" . $code;

				$client = curl_init($token_url);
				curl_setopt($client, CURLOPT_HTTPGET, TRUE);
				curl_setopt($client,  CURLOPT_RETURNTRANSFER , TRUE);

				$response =  curl_exec($client);

				curl_close($client);

				$params = null;
				parse_str($response, $params);

				$this->access_token = $params['access_token'];
				
				$_SESSION['access_token'] = $params['access_token'];

				$config = array(
				    'appId' => $this->app_id,
				   		'secret' => $this->app_secret,
							'fileUpload'=>$isFileUpload,
				);

				$this->facebook = new Facebook($config);
				$this->facebook->setAccessToken($this->access_token);
				$this->user_id = $this->facebook->getUser();

				$this->is_connected = true;
			}
			else{
				throw new FBConnectorException("The state does not match. You may be a victim of CSRF.");
			}
		}
	}

	/**
	 *
	 * Connect with previously stored access token
	 * @param string $accesstoken
	 * @param boolean $isFileUpload
	 */
	public function ConnectwithToken($accesstoken, $isFileUpload){
		
		$this->access_token = $accesstoken;

		$config = array(
				    'appId' => $this->app_id,
				   		'secret' => $this->app_secret,
							'fileUpload'=>$isFileUpload,
		);

		$this->facebook = new Facebook($config);
		$this->facebook->setAccessToken($this->access_token);
		$this->user_id = $this->facebook->getUser();

		$this->is_connected = true;
	}

	/**
	 *
	 * Get user's friend list
	 */
	public function getFriends($userID){		
		$fql = 'SELECT uid, name, pic_small_with_logo, profile_url from user'.
		' WHERE uid IN (SELECT uid2  FROM friend WHERE uid1 = me()) order by uid asc';	
		$this->friends = $this->FQLQuery($fql);
		return $this->friends;
	}
	
	/**
	 * 
	 * Enter description here ...
	 * @param unknown_type $userID
	 * @param unknown_type $limit
	 * @param unknown_type $offset
	 */
	public function getFriendList($userID, $limit, $offset){
		if ($this->friends == null)
			$this->getFriends($userID);
			
		$tempFriend = array();
		$totalLen = count($this->friends);
		$i = 0;
		$j = 0;
		for (;($i < $limit && ($i + $offset) < $totalLen); ++$i){
			$tempFriend[$j++] = $this->friends[$i + $offset];
		}
		
		return $tempFriend;
	}

	/**
	 *
	 * Get user profile informations
	 * @param $profileID - Profile ID
	 */
	public function getProfileInfo($profileID){
		$fql = 'SELECT id,can_post,url,name,pic,pic_square,pic_small,pic_big,pic_crop,type,username from profile WHERE id = '.$profileID;

		return $this->FQLQuery($fql);
	}

	/**
	 *
	 * Get user information
	 * @param  $userID - User ID
	 */
	public function getUserInfo($userID){
		$fql = 'SELECT uid, username, first_name, middle_name, last_name, name, pic_small, pic_big, pic_square, pic, affiliations,'.
		'profile_update_time, timezone, religion, birthday, birthday_date, sex, hometown_location, meeting_sex, meeting_for,'.
		'relationship_status,significant_other_id,political,current_location,activities,interests,is_app_user,music,tv,'.
		'movies,books,quotes,about_me,hs_info,education_history,work_history,notes_count,wall_count,status,has_added_app,'.
		'online_presence,locale,proxied_email,profile_url,email_hashes,pic_small_with_logo,pic_big_with_logo,'.
		'pic_square_with_logo,pic_with_logo,allowed_restrictions,verified,website,is_blocked,'.
		'contact_email,email,third_party_id,name_format,video_upload_limits,games,is_minor,work,education,'.
		'sports,favorite_athletes,favorite_teams,inspirational_people,languages,likes_count,friend_count,mutual_friend_count,can_post  from user WHERE uid = '.$userID;
			
		return $this->FQLQuery($fql);
	}
	
	/**
	 * 
	 * Enter description here ...
	 * @param unknown_type $fql
	 */
	public function getMainUserInfo($userID){
		$fql = 'SELECT uid, name, pic_small_with_logo, profile_url from user WHERE uid = '.$userID;
			
		return $this->FQLQuery($fql);
	}
	
	private function FQLQuery($fql){
		return $this->facebook->api(array(
			'method' => 'fql.query',
            	'query' => $fql,
		));
	}

	/**
	 *
	 * Post a message to profile
	 * @param $link - URL
	 * @param $message - message
	 */
	public function uploadURL($userID, $title, $link, $message, $description, $photo, $appname, $applink, $privacy, $caption, $self){

		$view = array(
        	'name' => $appname,
        	'link' => $applink,
		);

		if (true == $self){
			$request = array(
						'name'=> $title,
						'link' => $link,
						'message' => $message,
						'description'=> $description,
						'picture'=> $photo,
						'comment'=> $link,
						'caption'=> $caption,						
						'privacy' => json_encode($privacy),
						'actions' => json_encode($view),
			);
		}
		else{
			$request = array(
						'name'=> $title,
						'link' => $link,
						'message' => $message,
						'description'=> $description,
						'picture'=> $photo,
						'comment'=> $link,
						'caption'=> $caption,											
						'actions' => json_encode($view),
			);
		}

		return $this->facebook->api('/'.$userID.'/feed', 'POST',$request);
	}

	/**
	 *
	 * Post a comment
	 * @param $objectID
	 * @param $message
	 */
	public function postComment($objectID, $message){
		$response = $this->facebook->api($objectID.'/comments', 'POST',
		array(
				'message' => $message
		));
			
		return $response;
	}

	/**
	 *
	 * Post a like
	 * @param $objectID
	 */
	public function postLike($objectID){
		$response = $this->facebook->api($objectID.'/likes', 'POST');
		return $response;
	}

	/**
	 *
	 * Get album details
	 * @param $userID - user id
	 */
	public function getAlbums($userID){
		$fql = 'SELECT aid, object_id, owner, cover_pid, cover_object_id, name, created, modified, '.
			'description, location, size, link, visible, modified_major, edit_link, type, can_upload, '.
			'photo_count, video_count FROM album WHERE owner="'.$userID.'"';
		return $this->FQLQuery($fql);
	}
	
	/**
	 * 
	 * Delete a post or a comment
	 * @param post/commend ID $postid
	 */
	public function delete($postid){
		return $this->facebook->api("/" . $postid, 'DELETE');
	}

	/**
	 *
	 * Get Feeds for current user
	 */
	public function getMyFeeds($limit, $prevTime){
		$condition = '';
		if ($prevTime > 0)
			$condition = ' AND created_time < \''.$prevTime.'\'';
			
		$fql = 'SELECT post_id, actor_id, target_id, created_time, message, attachment, comments,likes FROM stream'.'
				WHERE filter_key in (SELECT filter_key FROM stream_filter WHERE uid=me() AND type=\'newsfeed\') '.
					'AND is_hidden = 0 '.$condition.' ORDER BY created_time desc LIMIT '.$limit;
		
		return $this->FQLQuery($fql);
	}
	
	/**
	 * Get Status information after inserted
	 */
	public function getPost($postID){
		$fql = '{"postinfo":"SELECT post_id, actor_id, target_id, created_time, message, attachment FROM stream  WHERE post_id = \''.$postID.'\'",'
    		. '"userinfo":"SELECT url, name, pic_small from profile WHERE id IN (SELECT actor_id FROM #postinfo)"}';
		
		return $this->facebook->api(array(
			'method' => 'fql.multiquery',
            	'queries' => $fql,
		));
		
	}

	/**
	 *
	 * Enter description here ...
	 * @param unknown_type $userID
	 */
	public function getFeeds($userID){
		$fql = 'SELECT post_id, actor_id, target_id, message,comments,likes FROM stream'.'
				WHERE filter_key in (SELECT filter_key FROM stream_filter WHERE uid='.$userID.' AND type=\'newsfeed\') AND is_hidden = 0';
		return $this->FQLQuery($fql);
	}

	/**
	 *
	 * Get posts made by user
	 * @param $userID
	 * @return array of user posts
	 */
	public function getPosts($userID){
		$fql = 'SELECT post_id, actor_id, target_id, message FROM stream WHERE source_id ='.$userID;
		return $this->FQLQuery($fql);
	}
	
	/**
	 * 
	 * Get all comments for post id 
	 * @param unknown_type $postID
	 */
	public function getComments($postID){
		$fql = 'SELECT fromid, post_id, post_fbid, object_id, xid, text, time from comment where post_id = \''.$postID.'\' ';
		return $this->FQLQuery($fql);		
	}
	

	/**
	 *
	 * Get current user profile information
	 */
	public function getMyProfile(){
		$user_profile = $this->facebook->api('/me','GET');
		return $user_profile;
	}

	/**
	 *
	 * Get whether user is connected to FB
	 */
	public function getIsConnected(){
		return $this->is_connected;
	}

	/**
	 *
	 * Get facebook user ID
	 */
	public function getUserID(){
		return $this->user_id;
	}

	/**
	 * Update the redirect URL
	 */
	public function setRedirectURL($redirectURL){
		$this->redirect_url = $redirectURL;
	}

	/**
	 *  Get the accesstoken for current user
	 */
	public function getAccesstoken(){
		return $this->access_token;
	}
	

}
?>

